import { computed } from 'vue'

import { cloneDeep, assign } from 'lodash-es'

const useTableBase = (queryParams, pageData, handleResetResponseData?: any) => {
    // 计算属性
    const rowSelection = computed(() => {
        return {
            onChange: handleRowSelectionChange,
            selectedRowKeys: pageData.selectedRowKeys
        } as {
            onChange: Function
            selectedRowKeys: any[]
        }
    })

    /**
     * table 多选反选操作变化
     * @param {*} selectedRowKeys tab选中的下标
     * @param {*} _selectedRows tab所有选中的数组
     */
    const handleRowSelectionChange = (selectedRowKeys: any[], _selectedRows) => {
        pageData.selectedRowKeys = selectedRowKeys
    }

    /**
     * 分页、排序、筛选变化时触发
     * @param {*} pagination
     * @param {*} filters
     * @param {*} sorter
     */
    const handleTableChange = (pagination, filters) => {
        const newPagination = cloneDeep(pagination)
        pageData.pagination = {
            ...newPagination,
            pageNo: newPagination.current
        }
        fetchTablesData(Object.assign(handleResetQueryParams(), filters))
    }

    // 组合查询form表单参数
    const handleResetQueryParams = () => {
        const params = assign(queryParams, {
            pageNo: pageData.pagination.pageNo,
            pageSize: pageData.pagination.pageSize
        })
        return params
    }

    // 查询条件发生改变
    const handleChangeParams = () => {
        // 主动搜索条件发生变化 所以页面和页面所有选中的值 设置为起始值，需要特殊处理的在页面重写此方法
        pageData.pagination.pageNo = 1
        pageData.selectedRowKeys = []
        fetchTablesData(handleResetQueryParams())
    }

    // 查询表格数据
    const fetchTablesData = (_params, callbackFn?: Function | undefined) => {
        pageData.loading = true
        pageData.fetchApi &&
            pageData
                .fetchApi(_params)
                .then(res => {
                    checkResponseData(res, callbackFn)
                })
                .finally(() => {
                    pageData.loading = false
                })
    }

    /**
     * 检测接口是否成功返回
     * @param {*} responseData 服务器相应数据
     */
    const checkResponseData = (responseData, callbackFn?: Function | undefined) => {
        if (responseData && responseData.content) {
            handleResponseSuccess(responseData, callbackFn)
        } else {
            handleResponseError()
        }
    }

    /**
     * 响应数据成功
     * @param {*} _response 服务器响应数据
     */
    const handleResponseSuccess = (_response, callbackFn?: Function | undefined) => {
        // 因为是列表数据 所以暂只关心 数据列表 和 总数 如果个性化页面或者个性化接口 则在当前页面重写此方法即可
        let resData = {
            content: _response.content || [],
            totalElements: _response.totalElements || 0
        }
        // 如果需要对响应数据做数据处理，因每个页面的处理逻辑都不一样，所以 handleResetResponseData 由具体的页面来重写
        if (handleResetResponseData) {
            resData = handleResetResponseData(resData)
        }
        pageData.data = resData.content
        // 克隆原始数据
        pageData.cacheData = cloneDeep(resData.content)
        pageData.pagination.total = resData.totalElements
        // 清空列选择项
        rowSelection.value.selectedRowKeys.splice(0, rowSelection.value.selectedRowKeys.length)
        callbackFn && callbackFn()
    }
    /**
     * 响应数据失败
     * @param {*} 服务器响应数据
     */
    const handleResponseError = () => {
        pageData.error = true
    }

    return {
        // 响应式数据
        queryParams,
        // 计算属性
        rowSelection,
        // 返回可能根据页面数据进行二次处理
        handleTableChange,
        // 查询条件发生改变
        handleChangeParams,
        fetchTablesData,
        handleResetQueryParams
    }
}

export default useTableBase
